package com.gec.system.filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gec.model.vo.LoginVo;
import com.gec.system.common.Result;
import com.gec.system.common.ResultCodeEnum;
import com.gec.system.service.ITripLoginLogService;
import com.gec.system.util.JwtHelper;
import com.gec.system.util.ResponseUtil;
import com.gec.system.utils.IpUtil;
import com.gec.system.utils.UserDetailImpl;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private RedisTemplate redisTemplate;
    private ITripLoginLogService iTripLoginLogService;

    private LoginVo loginVo;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager,
                                   RedisTemplate redisTemplate,
                                   ITripLoginLogService iTripLoginLogService) {
        this.setAuthenticationManager(authenticationManager);
        this.setPostOnly(false);
        //指定登录接口及提交方式，可以指定任意路径
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/system/index/login","POST"));
        this.redisTemplate = redisTemplate;
        this.iTripLoginLogService = iTripLoginLogService;
    }

    //用户认证
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            loginVo = new ObjectMapper().readValue(request.getInputStream(), LoginVo.class);
            System.out.println("请求的账号：" + loginVo.getUsername());
            System.out.println("请求的密码：" + loginVo.getPassword());
            Authentication authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.getPassword());
            return this.getAuthenticationManager().authenticate(authenticationToken);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return super.attemptAuthentication(request, response);
    }

    //成功认证问题  创建jwt并返回
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) throws IOException, ServletException {
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter out = response.getWriter();
//        UserDetails userDetails = (UserDetails) auth.getPrincipal();
//        //创建jwt
//        String jwt = JwtTokenUtil.createToken("gec", userDetails.getUsername(), 1800L);
//        System.out.println("创建了jwt：" + jwt);
//        out.write(new ObjectMapper().writeValueAsString(CommonResult.success(JwtTokenUtil.TOKEN_PREFIX + jwt)));
//        out.flush();
//        out.close();

        UserDetailImpl customUser = (UserDetailImpl) auth.getPrincipal();
        String token = JwtHelper.createToken(customUser.getITripUser().getId() + "", customUser.getUsername(),customUser.getITripUser().getUserImage());
        System.out.println("认证成功创建token: "+token);
        //使用redis保存权限数据
        System.out.println("redis存储权限："+customUser.getAuthorities());
        redisTemplate.opsForValue().set(customUser.getUsername(), JSON.toJSONString(customUser.getAuthorities()));

        //记录成功的日志
        iTripLoginLogService.recordLoginLog(customUser.getUsername(), 1, IpUtil.getIpAddress(request), "登录成功");

        String password = loginVo.getPassword();
        customUser.getITripUser().setPassword(password);
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("userInfo",customUser.getITripUser());
        ResponseUtil.out(response, Result.ok(map));
        System.out.println("认证成功-----结束");
    }

    //    失败认证的问题
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
//        response.setContentType("application/json;charset=utf-8");
//        PrintWriter out = response.getWriter();
//
//        out.write(new ObjectMapper().writeValueAsString(CommonResult.failed("登录失败")));
//        out.flush();
//        out.close();
        System.out.println("认证失败");
        if(e.getCause() instanceof RuntimeException) {
            ResponseUtil.out(response, Result.build(null, 204, e.getMessage()));
        } else {
            ResponseUtil.out(response, Result.build(null, ResultCodeEnum.LOGIN_MOBLE_ERROR));
        }
    }
}
